#include "appgalg.h"
#include "listoperation.h"
#include "IIRDesign/IIRFilterDesign.h"
#include "QDebug"
#include "QFile"
AppgAlg::AppgAlg()
{
    a=new double[3];
    b=new double[3];
    IIRDesign(2,1,500,0.3,3,a,b);

    a1=new double[3];
    b1=new double[3];
    IIRDesign(2,1,500,0.3,10,a1,b1);

    x=new double[3];
    y=new double[3];
    for(int i=0;i<3;i++)
    {
        x[i]=0;y[i]=0;
    }

}
AppgAlg::~AppgAlg()
{
    delete a;
    delete b;
    delete a1;
    delete b1;
    delete x;
    delete y;
}
void AppgAlg::computePrensentPPG_APPG(QList<double>ppg)
{
    double s1=ppg.at(0);
    int len=ppg.size();
    QList<double>temp_filter_ppg,temp_filterppg2;
    for(int i=0;i<500*6;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = s1;
        y[0] = b[0] * x[2] + b[1] * x[1] + b[2] * x[0] - a[1] * y[1] - a[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
    }
    for(int i=0;i<len;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = ppg.at(i);
        y[0] = b[0] * x[2] + b[1] * x[1] + b[2] * x[0] - a[1] * y[1] - a[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
        temp_filter_ppg.append(y[0]);
    }
    for(int i=0;i<500*6;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = s1;
        y[0] = b1[0] * x[2] + b1[1] * x[1] + b1[2] * x[0] - a1[1] * y[1] - a1[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
    }
    for(int i=0;i<len;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = ppg.at(i);
        y[0] = b1[0] * x[2] + b1[1] * x[1] + b1[2] * x[0] - a1[1] * y[1] - a1[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
        temp_filterppg2.append(y[0]);
    }

//    QFile file("C:\\Users\\haibi\\Desktop\\ppg_temp.txt");
//    if(!file.open(QIODevice::WriteOnly | QIODevice::Text)){
//        qDebug()<<"open==";
//        return;
//    }else{
//        QString content;
//        for(int i = 0; i < temp_filter_ppg.length(); i++){
//            content += QString::number(temp_filter_ppg.at(i)) + ",";
//        }
//        QTextStream in(&file);
//        in << content;
//        file.close();
//    }
    QList<int>ValleyPos,PeakPos;
    for(int i=0;i<len-102;i++){
        QList<double>sub_temp_filter_ppg=temp_filter_ppg.mid(i,101);
        int isPeak=0;
        for(int k=0;k<50;k++)
        {
            if((sub_temp_filter_ppg[50]>sub_temp_filter_ppg.at(k)) && (sub_temp_filter_ppg[50]>sub_temp_filter_ppg.at(50+k+1))){
                isPeak++;
            }
        }
        if(isPeak==50)
        {
            PeakPos.append(i+50);
        }
        int isValley=0;
        for(int k=0;k<50;k++)
        {
            if((sub_temp_filter_ppg[50]<sub_temp_filter_ppg.at(k)) && (sub_temp_filter_ppg[50]<sub_temp_filter_ppg.at(50+k+1))){
                isValley++;
            }
        }
        if(isValley==50)
        {
            ValleyPos.append(i+50);
        }
    }
    QList<int>ValleyPos_A;//定位到0.3-10hz的脉搏波信号起始点
    ListOperation lo;
    for(int i=0;i<ValleyPos.length();i++){
        int startPos=qMax(ValleyPos.at(i)-20,0);
        int endPos=qMin(len,ValleyPos.at(i)+20);
        QList<double>subppg=temp_filterppg2.mid(startPos,endPos-startPos);
        int pos=lo.ListMin_Index(subppg);
        ValleyPos_A.append(pos+startPos);//实际脉搏波起始点
    }

    QList<double>diff_ppg=lo.ListDiff(temp_filterppg2);
    float a2[] = { 1.0f,-1.8227f,0.8372f };
    float b2[] = { 0.0036f,0.0072f,0.0036f };
    double temp_diffppg=diff_ppg.at(0);
    for(int i=0;i<3000;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = temp_diffppg;
        y[0] = b2[0] * x[2] + b2[1] * x[1] + b2[2] * x[0] - a2[1] * y[1] - a2[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
    }
    QList<double>filter_diff_ppg;
    for(int i=0;i<len-1;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = diff_ppg.at(i);
        y[0] = b2[0] * x[2] + b2[1] * x[1] + b2[2] * x[0] - a2[1] * y[1] - a2[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
        filter_diff_ppg.append(y[0]);
    }
    QList<double>appg=lo.ListDiff(filter_diff_ppg);

    double temp_diffppg2=appg.at(0);
    for(int i=0;i<3000;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = temp_diffppg2;
        y[0] = b2[0] * x[2] + b2[1] * x[1] + b2[2] * x[0] - a2[1] * y[1] - a2[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
    }
    QList<double>filter_appg;
    for(int i=0;i<len-2;i++){
        x[0] = x[1];
        x[1] = x[2];
        x[2] = appg.at(i);
        y[0] = b2[0] * x[2] + b2[1] * x[1] + b2[2] * x[0] - a2[1] * y[1] - a2[2] * y[2];
        y[2] = y[1];
        y[1] = y[0];
        filter_appg.append(y[0]);
    }

    int valleyPos_len=ValleyPos_A.length();
    QList<int>RR=lo.ListDiff(ValleyPos_A);
    int startIndex=1;
    if(valleyPos_len>3)
        startIndex=valleyPos_len-3;
    else if(valleyPos_len>2)
    {
        startIndex=valleyPos_len-2;
    }else if(valleyPos_len>1)
    {
        startIndex=valleyPos_len-1;
    }

    QList<double>present_appg=lo.SubList(filter_appg,ValleyPos_A.at(startIndex)-40,RR.at(startIndex));
    QList<double>present_ppg=lo.SubList(temp_filterppg2,ValleyPos_A.at(startIndex)-40,RR.at(startIndex));

    Present_ppg.clear();
    Present_appg.clear();
    Present_appg=present_appg;
    Present_ppg=present_ppg;
    qDebug()<<"RR"<<RR;
    qDebug()<<"Present_appg"<<Present_appg.size();
    qDebug()<<"Present_ppg"<<Present_ppg.size();
//    ActualLen=RR.at(valleyPos_len-3);
    ActualLen=present_appg.size();
}
void AppgAlg::computeAccIndex(int age){
    QList<double>ppg=Present_ppg;
    QList<double>appg=Present_appg;
    int actualLen=ActualLen;
    ListOperation lo;
    QList<double>Actual_appg=lo.SubList(appg,0,actualLen);
    int A_Pos=lo.ListMax_Index(Actual_appg);
    int B_Pos=lo.ListMin_Index(lo.SubList(appg,A_Pos,qMin(70,actualLen-A_Pos-1)))+A_Pos;
    int C_Pos=lo.ListMax_Index(lo.SubList(appg,B_Pos,qMin(60,actualLen-B_Pos-1)))+B_Pos;
    int D_Pos=lo.ListMin_Index(lo.SubList(appg,C_Pos,qMin(50,actualLen-C_Pos-1)))+C_Pos;
    int E_Pos=lo.ListMax_Index(lo.SubList(appg,D_Pos,qMin(70,actualLen-D_Pos-1)))+D_Pos;
    if((B_Pos-A_Pos)<10)
        B_Pos=A_Pos+30;
    if((C_Pos-B_Pos)<20)
        C_Pos=B_Pos+40;
    if((D_Pos-C_Pos)<10)
        D_Pos=C_Pos+30;
    if((E_Pos-D_Pos)<15)
        E_Pos=D_Pos+25;
    if(A_Pos>actualLen-1)
        A_Pos=actualLen-1;
    if(B_Pos>actualLen-1)
        B_Pos=actualLen-1;
    if(C_Pos>actualLen-1)
        C_Pos=actualLen-1;
    if(D_Pos>actualLen-1)
        D_Pos=actualLen-1;
    if(E_Pos>actualLen-1)
        E_Pos=actualLen-1;
    double a_v=appg.at(A_Pos);
    double b_v=appg.at(B_Pos);
    double c_v=appg.at(C_Pos);
    double d_v=appg.at(D_Pos);
    double e_v=appg.at(E_Pos);
    VascularState=0;
    VascularAge=age;


    res="";
    double referv=qAbs(b_v/d_v);
    if(referv>4){
        SevenState.insert(0,1);
        SevenState.insert(1,0);
        SevenState.insert(2,0);
        SevenState.insert(3,0);
        SevenState.insert(4,0);
        SevenState.insert(5,0);
        SevenState.insert(6,0);
        VascularState=0;
        VascularAge=age-3;
        res="您的血液循环和血管状态很好，请您继续通过规律的生活习惯和身体锻炼保持现状。";
    }else{
        if(referv>3){
            SevenState.insert(0,0.6*referv-1.6);
            SevenState.insert(1,1-(0.6*referv-1.6));
            SevenState.insert(2,0);
            SevenState.insert(3,0);
            SevenState.insert(4,0);
            SevenState.insert(5,0);
            SevenState.insert(6,0);
            VascularState=1;
            VascularAge=age-2;
            res="您的血液循环和血管状态良好，请您继续通过规律的生活习惯和身体锻炼保持现状。";
        }else{
            if(referv>2){
                SevenState.insert(0,0);
                SevenState.insert(1,0.5*referv-0.5);
                SevenState.insert(2,1-(0.5*referv-0.5));
                SevenState.insert(3,0);
                SevenState.insert(4,0);
                SevenState.insert(5,0);
                SevenState.insert(6,0);
                VascularState=1;
                VascularAge=age-1;
                res="您的血液循环和血管状态较好，请您通过规律的生活习惯和身体锻炼保持现状。";
            }else{
                if(referv>1.5){
                    SevenState.insert(0,0);
                    SevenState.insert(1,0);
                    SevenState.insert(2,0.5*referv);
                    SevenState.insert(3,1-0.5*referv);
                    SevenState.insert(4,0);
                    SevenState.insert(5,0);
                    SevenState.insert(6,0);
                    VascularState=2;
                    VascularAge=age;
                    res="您的血液循环和血管状态处于血液粘度增加阶段，请您规律饮食，多吃水果蔬菜，加强身体锻炼，减缓血管老化速度。";
                }else{
                    if(referv>1){
                        SevenState.insert(0,0);
                        SevenState.insert(1,0);
                        SevenState.insert(2,0.3*referv);
                        SevenState.insert(3,1-0.3*referv);
                        SevenState.insert(4,0);
                        SevenState.insert(5,0);
                        SevenState.insert(6,0);
                        VascularState=2;
                        VascularAge=age+1;
                        res="您的血液循环和血管状态处于血液粘度增加阶段，请您规律饮食，多吃水果蔬菜，加强身体锻炼，减缓血管老化速度。";
                    }else{
                        if(referv>0.5){
                            SevenState.insert(0,0);
                            SevenState.insert(1,0);
                            SevenState.insert(2,0);
                            SevenState.insert(3,0.5*referv);
                            SevenState.insert(4,0.35*referv);
                            SevenState.insert(5,1-0.85*referv);
                            SevenState.insert(6,0);
                            VascularState=3;
                            VascularAge=age+2;
                            res="您的血液循环和血管状态处于血栓增加及沉淀阶段，请您规律饮食，多吃水果蔬菜，少食高盐高脂食物，加强身体锻炼，减缓血管老化速度。";
                        }else{
                            if(referv>0.3){
                                SevenState.insert(0,0);
                                SevenState.insert(1,0);
                                SevenState.insert(2,0);
                                SevenState.insert(3,0);
                                SevenState.insert(4,0.15*referv);
                                SevenState.insert(5,0.65*referv);
                                SevenState.insert(6,1-0.8*referv);
                                VascularState=4;
                                VascularAge=age+3;
                                res="您的血液循环和血管状态处于血栓形成阶段，请您规律饮食，多吃水果蔬菜，少食高盐高脂食物，加强身体锻炼，减缓血管老化速度。";
                            }else{
                                SevenState.insert(0,0);
                                SevenState.insert(1,0);
                                SevenState.insert(2,0);
                                SevenState.insert(3,0);
                                SevenState.insert(4,0);
                                SevenState.insert(5,0.5*referv);
                                SevenState.insert(6,1-0.5*referv);
                                VascularState=5;
                                VascularAge=age+4;
                                res="您的血液循环和血管状态处于血管内膜损害和硬化阶段，请您规律饮食，多吃水果蔬菜，少食高盐高脂食物，适量加强身体锻炼，减缓血管老化速度。";
                            }
                        }
                    }
                }
            }
        }
    }


    DPI=(b_v-c_v-d_v)/a_v*100;
    SP=b_v/a_v*100;
    BVT=c_v/a_v*100;
    RBV=d_v/a_v*100;
    abcde.clear();
    abcde.append(A_Pos);
    abcde.append(B_Pos);
    abcde.append(C_Pos);
    abcde.append(D_Pos);
    abcde.append(E_Pos);

    double min=Present_ppg.at(0);
    double max=Present_ppg.at(0);
    int len=Present_ppg.size();
    double mv=0;
    for(int i=0;i<len;i++)
    {
        if(min>Present_ppg.at(i))
            min=Present_ppg.at(i);
        if(max<Present_ppg.at(i))
            max=Present_ppg.at(i);
        mv+=Present_ppg.at(i);
    }
    mv=mv/len;
    K = (mv  - min) / (max-min)/2;


}
